import * as step from '@flow-step/step-toolkit'
import process from 'process'
import proxyquire from 'proxyquire'
import sinon from 'sinon';
import { expect } from 'chai';
import { getOssEndpoint } from '../src/ossDownload';
import axios from 'axios';

describe('download', () => {


    let stepExecStub: sinon.SinonStub;

    const suffix = 'txt';
    const meta = 'Cache-Control:no-cache#Content-Encoding:gzip';

    let fsStub = {
        statSync: sinon.stub(),
        existsSync: sinon.stub(),
        appendFile: sinon.stub(),
    };


    let stepStub = {
        certificate: {
            getOssRamServiceConnectionCertificate: sinon.stub(),
        },
        info: sinon.stub(),
        success: sinon.stub(),
        error: sinon.stub(),
        interaction:{
            addLink:sinon.stub(),
        }
    };


    beforeEach(() => {
        // Mock environment variables
        process.env.TARGET_PATH = 'some/download/path';
        process.env.PROJECT_DIR = '/project/dir';
        process.env.OSS_PATH = '/oss/path';
        process.env.FLOW_JOB_TOKEN = 'token';
        process.env.SERVICE_CONNECTION_ID = '123456';
        process.env.OSS_REGION = 'ucn-hangzhou';
        process.env.OSS_BUCKET = 'my-bucket';
        process.env.WORK_SPACE = '/workspace';
        process.env.METAS = JSON.stringify([{ key: suffix, value: meta }]);

        // Create stubs for dependencies
        fsStub.existsSync.returns(true);
        fsStub.statSync.returns({ mtime: new Date() });
        fsStub.appendFile.resolves();
        stepStub.certificate.getOssRamServiceConnectionCertificate.resolves({ accessKeyId: 'akid', accessKeySecret: 'secret', securityToken: 'token' });

        stepExecStub = sinon.stub(step.exec, 'call').resolves(0);

    });

    afterEach(() => {
        sinon.restore(); // Restore all stubs
    });

    it('should download files when conditions are met', async () => {
        const downloadProxy = proxyquire('../src/ossDownload', {
            fs: fsStub,
            '@flow-step/step-toolkit': stepStub,
        }).download;
        await downloadProxy();

        expect(stepStub.certificate.getOssRamServiceConnectionCertificate.calledOnce).to.be.true;
        expect(stepExecStub.calledOnce).to.be.true;
        expect(stepStub.interaction.addLink.calledOnce).to.be.true;
    });


    it('should throw an error if FLOW_JOB_TOKEN is missing', async () => {
        delete process.env.FLOW_JOB_TOKEN;
        const downloadProxy = proxyquire('../src/ossDownload', {
            fs: fsStub,
            '@flow-step/step-toolkit': stepStub,
        }).download;

        try {
            await downloadProxy();
        }catch (e:any){
            expect(e.message).to.equal('missing FLOW_JOB_TOKEN');
        }
    });

    it('should handle error when downloading files', async () => {
        stepExecStub.rejects(new Error('download error'))

        const downloadProxy = proxyquire('../src/ossDownload', {
            fs: fsStub,
            '@flow-step/step-toolkit': stepStub,
        }).download;

        try {
            await downloadProxy();
        }catch (e:any){
            expect(e.message).to.equal('download error');
            expect(stepStub.error.calledOnceWith('Failed to download files to oss'))
        }

    });
});

describe('getEndpoint Function', () => {
    let axiosGetStub: sinon.SinonStub;

    beforeEach(() => {
        // Mock axios.get 方法
        axiosGetStub = sinon.stub(axios, 'get');
    });

    afterEach(() => {
        // 恢复原始方法
        sinon.restore();
    });


    it('should return beijing internet  check connection 500', async () => {
        const endpoint = 'https://oss-cn-beijing.aliyuncs.com';
        process.env['OSS_REGION'] = 'cn-beijing';
        axiosGetStub.rejects({ status: 500 } );

        const result = await getOssEndpoint();
        expect(result).to.equal(endpoint);
    });
    it('should return beijing internet  check connection 403', async () => {
        const endpoint = 'https://oss-cn-beijing-internal.aliyuncs.com';
        process.env['OSS_REGION'] = 'cn-beijing';
        axiosGetStub.rejects({ status: 403 } );

        const result = await getOssEndpoint();
        expect(result).to.equal(endpoint);
    });
    it('should return beijing internet  check connection 200', async () => {
        const endpoint = 'https://oss-cn-beijing-internal.aliyuncs.com';
        process.env['OSS_REGION'] = 'cn-beijing';
        axiosGetStub.returns({ status: 200 } );

        const result = await getOssEndpoint();
        expect(result).to.equal(endpoint);
    });

});
